/**
 * Copyright (C) 2010-2016 eBusiness Information, Excilys Group
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed To in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ohosannotations.holder;

import static com.helger.jcodemodel.JExpr._null;
import static com.helger.jcodemodel.JExpr.cast;

import com.helger.jcodemodel.AbstractJClass;
import com.helger.jcodemodel.IJExpression;
import com.helger.jcodemodel.JBlock;

import org.ohosannotations.internal.process.ProcessHolder;

/**
 * FoundHolder
 *
 * @since 2021-07-20
 */
public abstract class FoundHolder {
    private GeneratedClassHolder holder;
    private AbstractJClass type;
    private IJExpression ref;
    private JBlock ifNotNullBlock;

    private boolean ifNotNullCreated = false;

    /**
     * FoundHolder
     *
     * @param holder 类持有者
     * @param type 类型
     * @param ref 表达式
     * @param block 板块
     */
    public FoundHolder(GeneratedClassHolder holder, AbstractJClass type, IJExpression ref, JBlock block) {
        this.holder = holder;
        this.type = type;
        this.ref = ref;
        ifNotNullBlock = block;
    }

    /**
     * getGeneratedClassHolder
     *
     * @return GeneratedClassHolder持有者
     */
    public GeneratedClassHolder getGeneratedClassHolder() {
        return holder;
    }

    /**
     * getRef
     *
     * @return IJExpression 表达式
     */
    public IJExpression getRef() {
        return ref;
    }

    /**
     * getOrCastRef
     *
     * @param type 抽象类型
     * @return IJExpression表达式
     */
    public IJExpression getOrCastRef(AbstractJClass type) {
        if (this.type.equals(type) || getBaseType().equals(type)) {
            return ref;
        } else {
            return cast(type, ref);
        }
    }

    /**
     * getBaseType
     *
     * @return AbstractJClass 抽象类型
     */
    protected abstract AbstractJClass getBaseType();

    /**
     * getIfNotNullBlock
     *
     * @return JBlock J板块
     */
    public JBlock getIfNotNullBlock() {
        if (!ifNotNullCreated) {
            ifNotNullBlock = ifNotNullBlock._if(ref.ne(_null()))._then();
            ifNotNullCreated = true;
        }
        return ifNotNullBlock;
    }

    /**
     * getEnvironment
     *
     * @return null
     */
    protected ProcessHolder.Classes getClasses() {
        return holder.getEnvironment().getClasses();
    }
}
